package com.sgcc.pda.sdk.utils;

import android.Manifest;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresPermission;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;

import com.sgcc.pda.baselibrary.utils.LogUtil;
import com.sgcc.pda.sdk.utils.db.SharepreferenceUtil;

/**
 * 检查网络是否可用工具类
 * Created by xuzl on 2016/9/22.
 */
public class NetWorkUtil {
    public static final int NETWORK_NONE = 0; // 没有网络连接
    public static final int NETWORK_2G = 2; // 2G
    public static final int NETWORK_3G = 3; // 3G
    public static final int NETWORK_4G = 4; // 4G
    private static final int NETWORK_5G = 5; // 5G
    public static final int NETWORK_WIFI = 10; // wifi连接
    public static final int NETWORK_MOBILE = 11; // 手机流量

    private static NetWorkUtil instance;

    // 电话管理器
    private TelephonyManager telephonyManager;
    // 移动信号强度监听器
    private PhoneStateListener phoneStateListener;
    private int rssi;// 信号强度

    public static synchronized NetWorkUtil getInstance() {
        if (null == instance) {
            instance = new NetWorkUtil();
        }
        return instance;
    }

    private NetWorkUtil() {
    }

    /**
     * 检查当前是否连接
     *
     * @param context
     * @return true表示当前网络处于连接状态，否则返回false
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public boolean isConnected(@NonNull Context context) {
        // 如果USB连接方式，直接返回true
        if (SharepreferenceUtil.getCommUsbEnable(context)) {
            return true;
        }
        if (!isNetworkConnected(context)) {
            // 网络未连接
            return false;
        }
        // 获取网络状态
        int state = getNetworkState(context);
        switch (state) {
            case NETWORK_WIFI:
                // WIFI 状态下，判断WIFI已连接和信号强度
                return getWifiRssi(context) > -100;
            case NETWORK_2G:
            case NETWORK_3G:
                // 2G网络和3G网络下,判断信号强度
                return getMobileRssi() > -80;
            case NETWORK_4G:
            case NETWORK_5G:
            case NETWORK_MOBILE:
                // 4G或其它网络下，判断信号强度
                return getMobileRssi() > -90;
            default:
                break;
        }
        return false;
    }


    /**
     * 开始监听信号强度
     *
     * @param context
     */
    public void startListen(@NonNull Context context) {
        if (telephonyManager == null) {
            // 获取telephonyManager
            telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        }
        if (phoneStateListener == null) {
            phoneStateListener = createPhoneStatListener();
        }
        if (telephonyManager != null) {
            // 监听信号强度
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        }
    }

    /**
     * 停止监听信号强度
     *
     * @param context
     */
    public void stopListen(@NonNull Context context) {
        if (telephonyManager != null && phoneStateListener != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }

    /**
     * 信号强度监听器
     */
    private PhoneStateListener createPhoneStatListener() {
        return new PhoneStateListener() {
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                super.onSignalStrengthsChanged(signalStrength);
                // 获取网络信号强度
                // 获取0-4的5种信号级别，越大信号越好,但是api23开始才能用
                // int level = signalStrength.getLevel();
                rssi = signalStrength.getGsmSignalStrength();
                LogUtil.d("信号强度RSSI : " + rssi);
            }
        };
    }

    /**
     * 返回移动信号强度
     */
    public int getMobileRssi() {
        return rssi;
    }

    /**
     * 网络是否连接
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public boolean isNetworkConnected(@NonNull Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        // 获取网络状态
        if (cm != null) {
            NetworkInfo networkInfo = cm.getActiveNetworkInfo();
            if (networkInfo != null) {
                return networkInfo.isConnected();
            } else return false;
        }
        return false;
    }

    /**
     * 获取WIFI信号强度
     */
    public int getWifiRssi(@NonNull Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wm.getConnectionInfo();
        // 0格 rssi<=-100
        // 1格 (-100, -88]
        // 2格 (-88, -77]
        // 3格 (-66, -55]
        // 4格 rssi>=-55
        return info.getRssi();
    }

    /**
     * 获取当前网络连接的类型
     *
     * @param context context
     * @return int
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public int getNetworkState(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (null == cm) { // 为空则认为无网络
            return NETWORK_NONE;
        }
        // 获取网络类型，如果为空，返回无网络
        NetworkInfo activeNetInfo = cm.getActiveNetworkInfo();
        if (activeNetInfo == null || !activeNetInfo.isAvailable()) {
            return NETWORK_NONE;
        }
        // 判断是否为WIFI
        NetworkInfo wifiInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (null != wifiInfo) {
            NetworkInfo.State state = wifiInfo.getState();
            if (null != state) {
                if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
                    return NETWORK_WIFI;
                }
            }
        }
        return getMobileType(context);
    }

    /**
     * 获取移动网络类型
     *
     * @param context
     * @return 2, 3, 4, 5G
     */
    public int getMobileType(Context context) {
        // 若不是WIFI，则去判断是2G、3G、4G网
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        final int type = tm.getNetworkType();
        switch (type) {
            /*
             GPRS : 2G(2.5) General Packet Radia Service 114kbps
             EDGE : 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
             UMTS : 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
             CDMA : 2G 电信 Code Division Multiple Access 码分多址
             EVDO_0 : 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
             EVDO_A : 3G 1.8mbps - 3.1mbps 属于3G过渡，3.5G
             1xRTT : 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
             HSDPA : 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
             HSUPA : 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
             HSPA : 3G (分HSDPA,HSUPA) High Speed Packet Access
             IDEN : 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 （属于2G，来自维基百科）
             EVDO_B : 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
             LTE : 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡，升级版 LTE Advanced 才是4G
             EHRPD : 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
             HSPAP : 3G HSPAP 比 HSDPA 快些
             */
            // 2G网络
            case TelephonyManager.NETWORK_TYPE_GPRS:
            case TelephonyManager.NETWORK_TYPE_CDMA:
            case TelephonyManager.NETWORK_TYPE_EDGE:
            case TelephonyManager.NETWORK_TYPE_1xRTT:
            case TelephonyManager.NETWORK_TYPE_IDEN:
                return NETWORK_2G;
            // 3G网络
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
            case TelephonyManager.NETWORK_TYPE_UMTS:
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
            case TelephonyManager.NETWORK_TYPE_HSDPA:
            case TelephonyManager.NETWORK_TYPE_HSUPA:
            case TelephonyManager.NETWORK_TYPE_HSPA:
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
            case TelephonyManager.NETWORK_TYPE_EHRPD:
            case TelephonyManager.NETWORK_TYPE_HSPAP:
                return NETWORK_3G;
            // 4G网络
            case TelephonyManager.NETWORK_TYPE_LTE:
                return NETWORK_4G;
            default:
                return NETWORK_MOBILE;
        }
    }
}
